package com.limeng.server;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class BootStrap {

    private int port = 8086;

    private Map<String,Servlet> servletMapping = new HashMap<>();

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    /**
     * 输出字符串
     * @throws IOException
     */
    protected void startup1(ServerSocket serverSocket) throws IOException {
        Socket socket = serverSocket.accept();
        InputStream inputStream = socket.getInputStream();

        byte[] b = new byte[1024];
        int readLen = inputStream.read(b);
        String param = "";
        if(readLen>0){
            param = new String(b);
            System.out.println(param);
        }
        OutputStream outputStream = socket.getOutputStream();
        String msg = "Hello, MiniCat";
        outputStream.write((ResponseUtil.return200(msg.length())+msg).getBytes());
        outputStream.flush();
        outputStream.close();
        socket.close();
    }

    protected void startup2(ServerSocket serverSocket) throws IOException {
        Socket socket = serverSocket.accept();
        InputStream inputStream = socket.getInputStream();
        Request request = new Request(inputStream);
        String url = request.getUrl();
        OutputStream outputStream = socket.getOutputStream();
        Response response = new Response(outputStream);
        if(url.endsWith(".html")){
            response.writeHtml(request.getUrl());
        }
        socket.close();
    }

    /**
     * 多线程
     * @throws IOException
     */
    protected void startup3() throws IOException {
        System.out.println("=====>>>Minicat start on port：" + port);
        ServerSocket serverSocket = new ServerSocket(port);
        while(true){
            Socket socket = serverSocket.accept();
            ServerThread runnable = new ServerThread(socket,servletMapping);
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }

    /**
     * 线程池
     * @throws IOException
     */
    protected void startup() throws IOException {

        System.out.println("=====>>>Minicat start on port：" + port);
        ServerSocket serverSocket = new ServerSocket(port);

        int corePoolSize = 50;
        int maximumPoolSize = 100;
        long keepAliveTime = 100l;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue workQueue = new ArrayBlockingQueue(100);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,
                         keepAliveTime, unit, workQueue, handler);
        while(true){
            Socket socket = serverSocket.accept();
            ServerThread runnable = new ServerThread(socket,servletMapping);
            executor.execute(runnable);
        }
    }

    public static void main(String[] args) throws Exception {

        BootStrap bootStrap = new BootStrap();
        bootStrap.init();
        bootStrap.startup();
    }

    public void init() throws DocumentException {
        InputStream resourceAsStream = BootStrap.class.getClassLoader().getResourceAsStream("web.xml");
        SAXReader reader = new SAXReader();
        Document document = reader.read(resourceAsStream);
        Element rootElement = document.getRootElement();
        List<Node> servletNodes = rootElement.selectNodes("//servlet");
        //<servlet-name>lagouServlet</servlet-name>
        servletNodes.forEach(node->{
            Element servletNameNode = (Element)node.selectNodes("servlet-name").get(0);
            String servletName = servletNameNode.getStringValue();

            Element servletClassNode = (Element)node.selectNodes("servlet-class").get(0);
            String servletClass = servletClassNode.getStringValue();
            //<url-pattern>/lagou</url-pattern>
            Element servletMappingNode = (Element)rootElement.selectSingleNode("//web-app//servlet-mapping[servlet-name='"+servletName+"']");

            String url = servletMappingNode.selectSingleNode("url-pattern").getStringValue();
            try {
                Class servlet = Class.forName(servletClass);
                servletMapping.put(url, (Servlet) servlet.newInstance());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        });
    }


}
